package com.efivestar.idm.api.service;

import java.io.IOException;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import com.efivestar.idm.api.service.lock.protocol.handler.LockProtocolHanderlIntf;
import com.efivestar.idm.api.util.ExceptionUtil;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;

@Component
public class NettyHttpServer implements ApplicationContextAware {
	private static Logger logger = LoggerFactory.getLogger(NettyHttpServer.class);
	
	@Value("${http.server.port:9080}")
    private int port;
    public static Map<String, LockProtocolHanderlIntf> lockProtocolHanderlIntfMap;

    public static DeviceService deviceService;
    public static int msgCnt = 0;

    private static String recvString = null;

    public static String getRecvString() {
        return recvString;
    }

    public void service() throws IOException {
    	logger.info("开启NETTY--HTTP服务..， 服务端口 {}", port);
    	EventLoopGroup bossGroup = new NioEventLoopGroup(); 
        EventLoopGroup workerGroup = new NioEventLoopGroup();  
        try {  
            ServerBootstrap b = new ServerBootstrap(); 
            b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) 
                    .childHandler(new ChannelInitializer<SocketChannel>() { 
                                @Override  
                                public void initChannel(SocketChannel ch) throws Exception {  
                                    ch.pipeline().addLast(new HttpServerCodec());/*HTTP 服务的解码器*/
                                    ch.pipeline().addLast(new HttpObjectAggregator(2048));/*HTTP 消息的合并处理*/
                                    ch.pipeline().addLast(new NettyHttpServerHandler());  
                                }  
                            }).option(ChannelOption.SO_BACKLOG, 128) 
                    .childOption(ChannelOption.SO_KEEPALIVE, false);
  
            ChannelFuture f;
			try {
				f = b.bind(port).sync();
				f.channel().closeFuture().sync();  
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
        } finally {  
            workerGroup.shutdownGracefully();  
            bossGroup.shutdownGracefully();  
        }  
    }
    
    @PostConstruct
    public void startServer() {
        Thread t = new Thread(new Runnable() {
            public void run() {
                try {
                	IotService.subscribeNotification();
                    service();
                } catch (Exception e) {
                    logger.info("开启NETTY--HTTP服务失败， 服务端口 {}", port);
                    logger.info(ExceptionUtil.getBriefExceptionStackTrace(e));
                }
            }
        });
        t.start();
    }
    
    @PreDestroy
    public void stop() throws IOException {
        logger.info("关闭NETTY-HTTP服务");

    }
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.lockProtocolHanderlIntfMap = applicationContext.getBeansOfType(LockProtocolHanderlIntf.class);
        this.deviceService=applicationContext.getBeansOfType(DeviceService.class).get("deviceService");
    }

    public static String recvBuf;

    public static String getRecvBuf() {
        return recvBuf;
    }

    public static void setRecvBuf(String recvBuf) {
        NettyHttpServer.recvBuf = recvBuf;
    }

}
